#include <types.h>
#include <string.h>

size_t strlen(const char *str)
{
    size_t ret_val;

    for (ret_val = 0; *str != '\0'; str++)
	ret_val++;

    return (ret_val);
}

char *strcpy(char *dst, const char *src)
{
    char *retval = dst;

    while (*src != '\0') {
	*dst++ = *src++;
    }
    *dst++ = *src++;

    return (retval);
}

size_t strncpy(char *dest, const char *src, size_t count)
{
    char *d = dest;
    const char *s = src;
    size_t n = count;

    /* Copy as many bytes as will fit */
    if (n != 0 && --n != 0) {
	do {
	    if ((*d++ = *s++) == 0)
		break;
	} while (--n != 0);
    }

    /* Not enough room in dst, add NUL and traverse rest of src */
    if (n == 0) {
	if (count != 0)
	    *d = '\0';		/* NUL-terminate dst */
	
	while (*s++);
    }

    return (size_t)(s - src - 1);	/* count does not include NUL */
}

int strcmp(const char *cs, const char *ct)
{
    register char res;

    while (1) {
	if ((res = *cs - *ct++) != 0 || !*cs++) {
	    break;
	}
    }

    return (res);
}

int strncmp(const char *s1, const char *s2, size_t n)
{
    const char *scan1, *scan2;
    int ret, t;

    if (n == 0)
	return 0;

    scan1 = &s1[0];
    scan2 = &s2[0];
    ret = *scan1 - *scan2;
    t = 1;
    while (ret == 0 && (t < n) && (*scan1) != '\0' && (*scan2) != '\0') {
	scan1++;
	scan2++;
	ret = *scan1 - *scan2;
	t++;
    }

    return (ret);
}

int toupper(int c)
{
    if (c >= 'a' && c <= 'z') {
	return (c + 'A' - 'a');
    } else {
	return (c);
    }
}

int tolower(int c)
{
    if (c >= 'A' && c <= 'Z') {
	return (c + 'a' - 'A');
    } else {
	return (c);
    }
}

long atol(const char *str)
{
    long n = 0;
    while (isdigit(*str)) {
	n = (n * 10) + *str - '0';
	str++;
    }

    return (n);
}

int isascii(int c)
{
    return ((c & ~0x7f) == 0);
}

int iscntrl(int c)
{
    return ((c) < ' ') || ((c) > 126);
}

int isdigit(int c)
{
    return ((c) >= '0') && ((c) <= '9');
}

int isgraph(int c)
{
    return ((c) > ' ') && ((c) <= 126);
}

int islower(int c)
{
    return (c >= 'a') && (c <= 'z');
}

int isprint(int c)
{
    return ((c) >= ' ') && ((c) <= 126);
}

int isspace(int c)
{
    return ((c) == ' ') || ((c) == '\f')
	|| ((c) == '\n') || ((c) == '\r')
	|| ((c) == '\t') || ((c) == '\v');
}

int isupper(int c)
{
    return (c >= 'A') && (c <= 'Z');
}

int isxdigit(int c)
{
    return isdigit(c) ||
	((c >= 'A') && (c <= 'F')) || ((c >= 'a') && (c <= 'f'));
}

int isalpha(int c)
{
    return islower(c) || isupper(c);
}

int isalnum(int c)
{
    return isalpha(c) || isdigit(c);
}

int ispunct(int c)
{
    return isgraph(c) && !isalnum(c);
}

int toascii(int c)
{
    return ((c) & 0x7f);
}

void *memsetw(void *dst, int val, size_t count)
{
    uint16_t *temp = (uint16_t *) dst;

    for (; count != 0; count--)
	*temp++ = val;

    return (dst);
}

void *memsetl(void *dst, int val, size_t count)
{
    uint32_t *temp = (uint32_t *) dst;

    for (; count != 0; count--)
	*temp++ = val;

    return (dst);
}

void *memset(void *dst, int val, size_t count)
{
    uchar *tmp = (uchar *) dst;

    for (; count != 0; count--)
	*tmp++ = val;

    return (dst);
}

void *memcpy(void *dst_ptr, const void *src_ptr, size_t count)
{
    void *ret_val = dst_ptr;
    const char *src = (const char *) src_ptr;
    char *dst = (char *) dst_ptr;

    if ((uint32_t) dst < (uint32_t) src) {
	/* copy up */
	for (; count != 0; count--)
	    *dst++ = *src++;
    } else {
	dst += (count - 1);
	src += (count - 1);
	for (; count != 0; count--)
	    *dst-- = *src--;
    }

    return (ret_val);
}

int memcmp(const void *s1, const void *s2, size_t n)
{
    if (n != 0) {
	const uchar *p1 = s1, *p2 = s2;

	do {
	    if (*p1++ != *p2++)
		return (*--p1 - *--p2);
	} while (--n != 0);
    }

    return 0;
}

void *bzero(void *dst, size_t count) 
{
    return (memset(dst,0,count));
}
